package org.batatasframework.support.event.internal;

import java.util.ArrayList;
import java.util.List;

import org.batatasframework.support.database.TableInfo;
import org.batatasframework.support.database.sql.TableInstance;
import org.batatasframework.support.database.sql.field.SelectFragment;
import org.batatasframework.support.database.sql.spi.TableCriterion;
import org.batatasframework.support.definition.FieldDefinition;
import org.batatasframework.support.definition.TableDefinition;
import org.batatasframework.support.searchable.SearchableInputStream;

import cn.bonoon.kernel.support.IOperator;

public class DefinitionSearchableRequest extends AbstractSearchableRequest<TableDefinition>{
	
//	private final TableDefinition searchableContext;
	private final List<FieldDefinition> fieldDefinitions = new ArrayList<>();

	/**
	 * 指定名称或别名的字段，这情况需要调用者清楚字段定义的名称等信息
	 * 根据这里定义的顺序进行排序
	 */
	public DefinitionSearchableRequest(IOperator operator, TableDefinition searchableContext, String...names) {
		super(operator);
		this.sourceTableMetadata = searchableContext;
		for(String name : names){
			this.fieldDefinitions.add(sourceTableMetadata.getDefinition(name));
		}
	}
	
	/**
	 * 全部的字段
	 */
	public DefinitionSearchableRequest(IOperator operator, TableDefinition searchableContext){
		super(operator);
		this.sourceTableMetadata = searchableContext;
		for(FieldDefinition fd : searchableContext.getColumns()){
			this.fieldDefinitions.add(fd);
		}
	}

	/**
	 * 指定字段的位置，这种情况下，别名可能是自动生成，但可以根据定义时的顺序来(或指定的顺序)来获取指定的字段
	 * 并且会根据这里指定的顺序进行重新排序
	 */
	public DefinitionSearchableRequest(IOperator operator, TableDefinition searchableContext, int...points) {
		super(operator);
		this.sourceTableMetadata = searchableContext;
		FieldDefinition[] fieldArray = searchableContext.getColumns();
		for(int point : points){
			this.fieldDefinitions.add(fieldArray[point]);
		}
	}
	
	/**
	 * 统计
	 */
	private boolean asStatisitics;
	private FieldDefinition groupField;
	private SearchableInputStream searchableInputStream;

	public void asStatisitics(String fieldName, boolean asStatisitics) {
		this.groupField = sourceTableMetadata.getDefinition(fieldName);
		this.asStatisitics = asStatisitics;
	}

	public void asStatisitics(int fieldIndex, boolean asStatisitics) {
		this.groupField = sourceTableMetadata.getDefinition(fieldIndex);
		this.asStatisitics = asStatisitics;
	}
	
	public void asGroup(String fieldName){
		this.groupField = sourceTableMetadata.getDefinition(fieldName);
	}

	public void setGroup(int fieldIndex){
		this.groupField = sourceTableMetadata.getDefinition(fieldIndex);
	}

	@Override
	public TableInfo getTableInfo() {
		return sourceTableMetadata.getTableInfo();
	}
	
	@Override
	public void resolve(TableInstance tableInstance, TableCriterion tableCriterion) throws Exception {
		SelectFragment selectFragment = null;
		if(null != groupField){
			selectFragment = groupField.buildFragment(tableCriterion);
		}
		searchableInputStream = buildInputStream(selectFragment, asStatisitics);
		
		for(FieldDefinition fieldDefinition : fieldDefinitions){
			fieldDefinition.buildFragment(tableCriterion);
		}
	}

	public SearchableInputStream getSearchableInputStream() {
		return searchableInputStream;
	}
}
